package com.yyl.common.system.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yyl.common.api.Result;
import com.yyl.common.constant.Inter.CommonConstant;
import com.yyl.common.system.api.ISysBaseAPI;
import com.yyl.common.util.CommonUtils;
import com.yyl.common.util.RestUtil;
import com.yyl.common.util.oConvertUtils;
import com.yyl.common.util.token.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;

//用户表 前端控制器
@Slf4j
@RestController
@RequestMapping("/sys/common")
public class CommonController {
// 系统基础的api
	@Autowired
	private ISysBaseAPI sysBaseAPI;
	
	@Value(value = "${jeecg.path.upload}")
	private String uploadPath;
	
	// 本地：local minio：minio 阿里：alioss
	@Value(value = "${jeecg.uploadType}")
	private String uploadType;
	
	/**
	 * 没有权限返回值
	 * @return
	 */
	@GetMapping("/403")
	public Result<?> noauth(){
		return Result.error("没有权限，请联系管理员授权");
	}
	@PostMapping(value = "/upload")
	public Result<?> upload(HttpServletRequest request, HttpServletResponse response){
		Result<?> result=new Result<>();
		String savePath="";
		String bizPath=request.getParameter("biz");
		MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
		MultipartFile file=multipartRequest.getFile("file");// 获取上传文件对象
		if(oConvertUtils.isEmpty(bizPath)){
			if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
				// 未指定目录，则用阿里云默认目录 upload
				bizPath="upload";
			}else {
				bizPath="";
			}
		}
		if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
			//针对jeditor编辑器如何使 lcaol模式，采用 base64格式存储
			String jeditor=request.getParameter("jeditor");
			if (oConvertUtils.isNotEmpty(jeditor)){
				result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
				result.setSuccess(true);
				return result;
			}else {
				savePath=this.uploadLocal(file,bizPath);
			}
		}else {
			savePath=sysBaseAPI.upload(file,bizPath,uploadType);
		}
		if(oConvertUtils.isNotEmpty(savePath)){
			result.setMessage(savePath);
			result.setSuccess(true);
		}else {
			result.setMessage("上传失败！");
			result.setSuccess(false);
		}
		return result;
	}
	
	/**
	 * 本地文件上传
	 * @param mf 文件
	 * @param bizPath 自定义路径
	 * @return
	 */
	private String uploadLocal(MultipartFile mf,String bizPath){
		try{
			String ctxPath=uploadPath;
			String fileName=null;
			File file=new File(ctxPath+File.separator+bizPath+File.separator);
			if(!file.exists()){
				file.mkdirs();// 创建文件根目录
			}
			String orgName=mf.getOriginalFilename();// 获取文件名
			assert orgName!=null;
			orgName = CommonUtils.getFileName(orgName);
			if (orgName.contains(".")){
				fileName=orgName.substring(0,orgName.lastIndexOf("."))+"_"+System.currentTimeMillis()+orgName.substring(orgName.indexOf("."));
			}else {
				fileName=orgName+"_"+System.currentTimeMillis();
			}
			String savePath=file.getPath()+File.separator+fileName;
			File savefile=new File(savePath);
			FileCopyUtils.copy(mf.getBytes(),savefile);
			String dbpath=null;
			if (oConvertUtils.isNotEmpty(bizPath)){
				dbpath=bizPath+File.separator+fileName;
			}else {
				dbpath=fileName;
			}
			if (dbpath.contains("\\")){
				dbpath=dbpath.replace("\\","/");
			}
			return dbpath;
		}catch (IOException e){
			log.error(e.getMessage(),e);
		}
		return "";
	}
	
	/**
	 * 预览图片
	 * 请求地址：http://localhost:8080/common/view/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
	 * @param request
	 * @param response
	 */
	@GetMapping(value = "/view/**")
	public void view(HttpServletRequest request,HttpServletResponse response){
		// ISO-8859-1 ==> UTF-8 进行编码转换
		String imgPath=extractPathFromPattern(request);
		// 其余处理不记
		InputStream inputStream=null;
		OutputStream outputStream=null;
		try{
			imgPath=imgPath.replace("..","");
			if (imgPath.endsWith(",")){
				imgPath=imgPath.substring(0,imgPath.length()-1);
			}
			response.setContentType("image/jpeg;charset=utf-8");
			String localPath=uploadPath;
			String imgurl=localPath+File.separator+imgPath;
			inputStream =new BufferedInputStream(new FileInputStream(imgurl));
			outputStream=response.getOutputStream();
			byte[] buf=new byte[1024];
			int len;
			while ((len=inputStream.read(buf))>0){
				outputStream.write(buf,0,len);
			}
		  response.flushBuffer();
		}catch (IOException e){
			log.error("预览图片失败"+e.getMessage());
			// e.printStackTrace();
		}finally {
			if (inputStream!=null){
				try{
					inputStream.close();
				}catch (IOException e){
					log.error(e.getMessage(),e);
				}
			}
			if (outputStream!=null){
				try{
					outputStream.close();
				}catch (IOException e){
					log.error(e.getMessage(),e);
				}
			}
		}
	
	}
	/**
	 * @param modelAndView
	 * @return
	 * @功能：pdf预览Iframe
	 */
	@RequestMapping("/pdf/pdfPreviewIframe")
	public ModelAndView pdfPreviewIframe(ModelAndView modelAndView) {
		modelAndView.setViewName("pdfPreviewIframe");
		return modelAndView;
	}
	/**
	 * 把指定URL后的字符串全部截断当成参数
	 * 这么做是为了防止URL中包含中文或者特殊字符（/等）时，匹配不了的问题
	 *
	 * @param request
	 * @return
	 */
	private static String extractPathFromPattern(final HttpServletRequest request) {
		String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
		String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
		return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
	}
	
	/**
	 * 中转HTTP请求，解决跨域问题
	 *
	 * @param url 必填：请求地址
	 * @return
	 */
	@RequestMapping("/transitRESTful")
	public Result<?> transitRESTful(@RequestParam("url") String url, HttpServletRequest request) {
		try {
			ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
			// 中转请求method、body
			HttpMethod method = httpRequest.getMethod();
			JSONObject params;
			try {
				params = JSON.parseObject(JSON.toJSONString(httpRequest.getBody()));
			} catch (Exception e) {
				params = new JSONObject();
			}
			// 中转请求问号参数
			JSONObject variables = JSON.parseObject(JSON.toJSONString(request.getParameterMap()));
			variables.remove("url");
			// 在 headers 里传递Token
			String token = TokenUtils.getTokenByRequest(request);
			HttpHeaders headers = new HttpHeaders();
			headers.set("X-Access-Token", token);
			// 发送请求
			String httpURL = URLDecoder.decode(url, "UTF-8");
			ResponseEntity<String> response = RestUtil.request(httpURL, method, headers, variables, params, String.class);
			// 封装返回结果
			Result<Object> result = new Result<>();
			int statusCode = response.getStatusCodeValue();
			result.setCode(statusCode);
			result.setSuccess(statusCode == 200);
			String responseBody = response.getBody();
			try {
				// 尝试将返回结果转为JSON
				Object json = JSON.parse(responseBody);
				result.setResult(json);
			} catch (Exception e) {
				// 转成JSON失败，直接返回原始数据
				result.setResult(responseBody);
			}
			return result;
		} catch (Exception e) {
			log.debug("中转HTTP请求失败", e);
			return Result.error(e.getMessage());
		}
	}
	
}
